package com.autel.webrtc.demo.aop;

import com.autel.webrtc.demo.common.Result;
import com.autel.webrtc.demo.common.storage.ThreadLocalHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;


/**
 * 全局的的异常拦截器（拦截所有的控制器）（带有@RequestMapping注解的方法上都会拦截）
 *
 * @author huawenyao
 * @date 2020.4.10
 */

@ControllerAdvice
@Order(1)
public class GlobalExceptionHandler {


    private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    private Result buildErrorResult(Exception e) {
        Result rs = new Result();
        rs.setSuccess(false);
        rs.error500(e.getMessage());
        return rs;
    }

    /**
     * 功能描述: 表单参数验证异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result paramException(Exception e) {

        ThreadLocalHolder.getInstance().clearAll();
        StringBuilder sb = new StringBuilder("");
        if(e instanceof MethodArgumentNotValidException){
            MethodArgumentNotValidException me = (MethodArgumentNotValidException) e;
            log.error("表单参数验证异常:", me);
            BindingResult bindingResult = me.getBindingResult();

            bindingResult.getFieldErrors().forEach(error -> {
                sb.append(error.getDefaultMessage());
            });
        }
        if(e instanceof MissingServletRequestParameterException){
            MissingServletRequestParameterException me = (MissingServletRequestParameterException) e;
            sb.append("请求参数: [")
                    .append(me.getParameterName())
                    .append("]")
                    .append("不能为空");
        }

        return Result.error( sb.toString());
    }

    /**
     * 拦截业务异常
     */
//    @ExceptionHandler(BusinessException.class)
//    @ResponseStatus(HttpStatus.OK)
//    @ResponseBody
//    public Result notFount(BusinessException e) {
//
//        ThreadLocalHolder.getInstance().clearAll();
//        log.error("业务异常:", e);
//        return Result.error(e.getMessage);
//    }


    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public Result notFount(RuntimeException e) {

        ThreadLocalHolder.getInstance().clearAll();
        log.error("运行时异常:", e);

       return Result.error(e.getMessage());
    }

    @ExceptionHandler(AssertionError.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result assetError(AssertionError e) {

        ThreadLocalHolder.getInstance().clearAll();
        log.error("运行时异常:", e);
        return  Result.error(e.getMessage());
    }

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public Result IllegalArgumentError(IllegalArgumentException e) {

        ThreadLocalHolder.getInstance().clearAll();
        log.error("运行时异常:", e);
        return  Result.error(e.getMessage());
    }
}
